/*
 * ExtTableLN.java
 *
 * $Id: ExtTableLN.java,v 1.2 2009-03-02 15:31:23 mario Exp $
 *
 * Author: Mario García García - Imagos 2007
 */
package org.ceteca.explica.core.extTables;

import java.util.ArrayList;
import java.util.Map;

import org.ceteca.explica.core.InterfaceErrors;
import org.ceteca.explica.core.util.OperationResult;
import org.ceteca.explica.core.util.ResultMessage;
import org.ceteca.explica.server.ServerContext;

/**
 * This class implements the table extension model. It's a part of the business logic
 * layer and encapsulates the access to the extended database tables, providing methods 
 * to query, update, insert or delete extended elements.
 * <br/>
 * To implement these functionalities it uses a HashMap interface that stores all the 
 * values of the original table plus the extended values defined for the group/family 
 * the element belongs to. This HashMap interface is the most adaptable way to store an
 * undefinided and unlimited amount of data that can be stores into these extensible
 * tables.
 * <br/>
 * Responsibilities:
 * <li>
 * 	<ul> Provide access to extension fields definition metadata (format, type, length, 
 * nullable, etc.) for extended items. </ul>
 *  <ul> Provide access to extension fields values for extended items. </ul>
 *  <ul> Query the database by the primary key or by any other query criteria for extended
 *  items. These queries should return the whole items result of the query (including
 *  original values plus extended values). </ul>
 *  <ul> Insert new extended elements. </ul>
 *  <ul> Update extension values for extended items. </ul>
 *  <ul> Delete extension values for extended items. </ul>
 * </li>
 */
public class ExtTableLN {
	
	// Implementation of Singleton pattern.
	private static ExtTableLN instance = null;
	
	/**
	 * Default constructor of the class ExtTableLN.
	 */
	private ExtTableLN() {
	}
	
	/**
	 * Returns the Singleton instance of class ExtTableLN.
	 * @return ExtTableLN, the Singleton instance of ExtTableLN.
	 */
	public static ExtTableLN getInstance() {
		if (instance == null)
			instance = new ExtTableLN();
	
		return instance;
	}
	
	/**
	 * Return the extension table definition, including the list of all the
	 * extension fields defined for the table.
	 * @param idExtTable long, internal id of the extension table.
	 * @return ExtTableOT, extension table definition.
	 * @throws ExtTableException in case any error take place during the
	 * query operation.
	 */
	public ExtTableOT getExtensionTableDefinition(long idExtTable) throws ExtTableException {
		// Call the DAO to query the database and get the extension table definition.
		ExtTableDAO dao = new ExtTableDAO();
		return dao.getExtensionTableDefinition(idExtTable);
	}
	
	/**
	 * Return the extension table definition, including the list of all the
	 * extension fields defined for the table.
	 * @param codExtTable String, external code of the extension table.
	 * @return ExtTableOT, extension table definition.
	 * @throws ExtTableException in case any error take place during the
	 * query operation.
	 */
	public ExtTableOT getExtensionTableDefinition(String codExtTable) throws ExtTableException {
		// Call the DAO to query the database and get the extension table definition.
		ExtTableDAO dao = new ExtTableDAO();
		return dao.getExtensionTableDefinition(codExtTable);
	}
	
	/**
	 * Return all the values stored for an extended item. Include all the fields
	 * defined for the extension table and their correspondent value (if anyone 
	 * has been defined).
	 * @param idValue Long, internal id of the extended item. 
	 * @param codExtTable String, external code of the extension table.
	 * @return Map, set of all the extension fields and their values for the 
	 * extended item.
	 * @throws ExtTableException, in case any error take place during the query 
	 * operation.
	 */
	public Map getExtendedItemValues(Long idValue, String codExtTable) throws ExtTableException {
		// Call the DAO to query the database and get the extended values for the item.
		ExtTableDAO dao = new ExtTableDAO();
		return dao.getExtendedItemValues(idValue, codExtTable);
	}
	
	/**
	 * Query the database to get the extension field (definition and value) of 
	 * an extended item. 
	 * @param idValue long, Value of the internal id of the extended item. It's
	 * the primary key of the extended item.
	 * @param codExtField String, External code of the extension field.
	 * @throws ExtTableException, in case any error take place during
	 * the update operation.
	 * @return ExtFieldOT, definition and value of the extension field queried.
	 */
	public ExtFieldOT getExtensionField(Long idValue, String codExtField) throws ExtTableException {
		// Call the DAO to query the database and get the extension field for the item.
		ExtTableDAO dao = new ExtTableDAO();
		return dao.getExtensionField(idValue, codExtField);
	}
	
	/**
	 * Update the value of an extension field.
	 * @param extField ExtFieldOT, extended field to update.
	 * @param idItem long, internal id of the extended item.
	 * @throws ExtTableException, in case any error take place during
	 * the update operation. 
	 */
	public void saveExtendedFieldValue(ExtFieldOT extField, long idItem) throws ExtTableException {
		ExtTableDAO dao = new ExtTableDAO();
		
		// Set the id of the original item
		if (extField != null)
			extField.setIdValue(idItem);
		
		// Call the DAO to update the database with the extension field string value. 
		dao.saveExtendedFieldValue(extField);
	}
	
	
	/**
	 * Update the value of all the extension fields defined for an extended item.
	 * @param lExtFields ArrayList, list of all the extension fields whose values
	 * must be updated.
	 * @param idItem long, internal id of the extended item.
	 * @return OperationResult, result of the save extended values operation.
	 * @throws ExtTableException, in case any error take place during
	 * the update operation.
	 */
	public OperationResult saveExtendedItemValues(ArrayList lExtFields, long idItem) throws ExtTableException {
		ExtTableDAO dao = new ExtTableDAO();
		OperationResult result = new OperationResult();
		try {
			dao.saveExtendedItemValues(lExtFields, idItem);
			result.addResultMessage(OperationResult.RESULT_OK, 
					ServerContext.getInstance().getMsgCatalog().newResultMessage(InterfaceErrors.MSG_SAVE_EXT_VALUES_OK));
		}
		catch (ExtTableException ex) {
			result.addResultMessage(OperationResult.RESULT_ERROR, 
					ServerContext.getInstance().getMsgCatalog().newResultMessage(ex.getErrCode()));
		}
		// Call the DAO to update the database with the extension field string value. 
		return result;
	}
	
	/**
	 * Update the value of all the extension fields defined for an extended item.
	 * @param mExtFields Map, set of all the extension fields whose values
	 * must be updated.
	 * @param idItem long, internal id of the extended item.
	 * @throws ExtTableException, in case any error take place during
	 * the update operation.
	 */
	public void saveExtendedItemValues(Map mExtFields, long idItem) throws ExtTableException {
		ExtTableDAO dao = new ExtTableDAO();
		
		// Call the DAO to update the database with the extension field string value. 
		dao.saveExtendedItemValues(mExtFields, idItem);
	}
	
	/**
	 * Delete the extension field values of an extended item.
	 * @param codExtTable String, External code of the extension table. 
	 * @param idItem long, internal id of the extended item. 
	 * @throws ExtTableException, in case any error take place during
   	 * the query operation. 
	 */
	public void deleteExtendedItemValues(String codExtTable, long idItem) throws ExtTableException {
		ExtTableDAO dao = new ExtTableDAO();
		
		// Call the DAO to delete the extension values of the extended item from DB. 
		dao.deleteExtendedItemValues(codExtTable, idItem);
	}
	
	/**
	 * Update or add a new extension field definition.
	 * @param extField ExtFieldOT, extended field to update/add.
	 * @throws ExtTableException, in case any error take place during
   	 * the update operation. 
	 */
	public void saveExtensionField(ExtFieldOT extField) throws ExtTableException {
		ExtTableDAO dao = new ExtTableDAO();
		
		// Call the DAO to save the extension field definition in the DB. 
		dao.saveExtensionField(extField);
	}
	
	/**
	 * Delete the extension field definition and all the values stored for it. 
	 * @param codExtField String, External code of the extension field.
	 * @throws ExtTableException, in case any error take place during
	 * the delete operation.
	 */
	public void deleteExtensionField(String codExtField) throws ExtTableException {
		ExtTableDAO dao = new ExtTableDAO();
		
		// Get the extension field from the DB
		ExtFieldOT extField = this.getExtensionField(null, codExtField);
		
		// Call the DAO to delete the extension field
		dao.deleteExtensionField(extField);
	}
	
	/**
	 * Delete the extension field definition and all the values stored for it. 
	 * @param extField ExtFieldOT, the extension field to delete.
	 * @throws ExtTableException, in case any error take place during
	 * the delete operation.
	 */
	public void deleteExtensionField(ExtFieldOT extField) throws ExtTableException {
		ExtTableDAO dao = new ExtTableDAO();
		
		// Call the DAO to delete the extension field
		dao.deleteExtensionField(extField);
	}
	
	/**
	 * Update or add a new extension table definition.
	 * @param extTable ExtTableOT, extended table to update/add.
	 * @throws ExtTableException, in case any error take place during
   	 * the update operation. 
	 */
	public void saveExtensionTableDefinition(ExtTableOT extTable) throws ExtTableException {
		ExtTableDAO dao = new ExtTableDAO();
		
		// Call the DAO to save the extension table definition into the DB
		dao.saveExtensionTableDefinition(extTable);
	}
	
	/**
	 * Delete the extension table definition and all the fields and
	 * values stored for it. 
	 * @param extTable ExtTableOT, extension table to delete.
	 * @throws ExtTableException, in case any error take place during
	 * the delete operation.
	 */
	public void deleteExtensionTableDefinition(ExtTableOT extTable) throws ExtTableException {
		ExtTableDAO dao = new ExtTableDAO();
		
		// Call the DAO to delete the extension table definition from the DB
		dao.deleteExtensionTableDefinition(extTable);
	}
	
	/**
	 * Delete the extension table definition and all the fields and
	 * values stored for it. 
	 * @param codExtTable String, external code of the extension table to delete.
	 * @throws ExtTableException, in case any error take place during
	 * the delete operation.
	 */
	public void deleteExtensionTableDefinition(String codExtTable) throws ExtTableException {
		ExtTableDAO dao = new ExtTableDAO();
		
		ExtTableOT extTable = dao.getExtensionTableDefinition(codExtTable);
		
		// Call the DAO to delete the extension table definition from the DB
		dao.deleteExtensionTableDefinition(extTable);
	}
	
	/**
	 * Returns tag Id assigned to CVS source file.
	 */
	public static String getRevision() {
		return "$Id: ExtTableLN.java,v 1.2 2009-03-02 15:31:23 mario Exp $";
	}
}